package classification.classifier;

import static preprocess.XMLContracter.ATTRIBUTE;
import static preprocess.XMLContracter.NESTING;
import static preprocess.XMLContracter.REPETITION;

import java.io.File;
import java.util.ArrayList;

import org.dom4j.Document;
import org.dom4j.io.SAXReader;

import preprocess.XMLContracter;
import preprocess.XMLDoc;

import similarity.SimpleTEDSimilarity;

public class ClassifierByTED extends Classifier
{
    private SimpleTEDSimilarity calcSimilarity = null;

    private XMLContracter       contracter     = null;

    public ClassifierByTED()
    {
        /* 创建similarity计算对象 */
        this.calcSimilarity = new SimpleTEDSimilarity();

        this.contracter = new XMLContracter();
    }

    public void run()
    {
        try
        {
            /* 初始化得到分类所需要的部分参数和文件等信息 */
            this.init();

            /* 调用Cross-Validation程序 */
            double avgPrec = 0.0;
            if ((avgPrec = this.crossValidation()) == -1)
            {
                stdErr.println("Error occur in crossValidation process");
            }
            else
            {
                stdOut.println("The avg precision of C-V is： " + avgPrec);
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }

    protected boolean training(final ArrayList<File> fileArr)
    {
        try
        {
            /* 找到训练文件的docID信息 */
            this.docIDSet = this.exploreDocID(fileArr);

            return true;
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            return false;
        }
    }

    protected double test(final ArrayList<File> fileArr,
            final ArrayList<File> traFileArr)
    {
        try
        {
            stdOut.println("Test process is running...");
            double succ = 0;

            int traFileNum = traFileArr.size();
            int tesFileNum = fileArr.size();

            double[] simiResult = null;
            for (int testIndex = 0; testIndex < tesFileNum; testIndex++)
            {
                simiResult = new double[traFileNum];

                File testFile = fileArr.get(testIndex);
                XMLDoc testXMLDoc = this.getXMLDoc(testFile);
                testXMLDoc.getInfo();

                for (int traIndex = 0; traIndex < traFileNum; traIndex++)
                {
                    File traFile = traFileArr.get(traIndex);
                    XMLDoc traXMLDoc = this.getXMLDoc(traFile);
                    traXMLDoc.getInfo();

                    simiResult[traIndex] = this.calcSimilarity.calcSimilarity(
                            testXMLDoc, traXMLDoc);
                }

                /* 找到KNN类别 */
                String category = this.KNNValueClassify(simiResult,
                        this.docIDSet).getCategory();

                if (category == null)
                {
                    stdErr.println("Error occur in KNNValueClassify function");
                }

                /* 判断分类是否正确 */
                if (this.evaluate(testXMLDoc.getDocID(), category))
                {
                    succ++;
//                    stdOut.println(testXMLDoc.getDocID()
//                            + ": is succeed classified to " + category);
                }
                else
                {
                    stdErr.println(testXMLDoc.getDocID()
                            + ": is classified to " + category
                            + ", but desired category is :"
                            + this.categoryMap.get(testXMLDoc.getDocID()));
                }
            }
            double precision = (double) succ / (double) tesFileNum;
            stdOut.println("Test process is end...");
            stdOut.println("\tTest precision is: " + precision);

            return precision;
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            return -1;
        }
    }
}
